package com.googlecode.chios.jnet.worker;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 
 * 工作线程池
 * 
 * @author luzj
 * 
 */
public class WorkerContext {

	public static final ThreadLocal<Executor> EXECUTORS = new ThreadLocal<Executor>();

	private AioWorker[] workers;

	private AtomicInteger indexs = new AtomicInteger(0);

	private static final int DEFAULT_WORKER_COUNT = Runtime.getRuntime().availableProcessors() * 2;

	private WorkerContext() {
		//none use
	}
	
	public AioWorker nextWorker() {
		return workers[Math.abs(indexs.getAndIncrement() % workers.length)];
	}
	
	public static WorkerContext open() {
		return open(Executors.newCachedThreadPool());
	}

	public static WorkerContext open(Executor executor) {
		return open(executor, DEFAULT_WORKER_COUNT);
	}
	
	public static WorkerContext open(Executor executor, int workerCount) {
		WorkerContext context = new WorkerContext();
		context.workers = new AioWorker[workerCount];
		for (int i = 0; i < workerCount; i++) {
			context.workers[i] = new AioWorker(i, executor);
		}
		return context;
	}

	public static void startWorker(final Executor executor, final Runnable worker) {
		if (executor == null) {
			throw new NullPointerException("parent");
		}
		if (worker == null) {
			throw new NullPointerException("runnable");
		}

		executor.execute(new Runnable() {
			public void run() {
				EXECUTORS.set(executor);
				try {
					worker.run();
				} finally {
					EXECUTORS.remove();
				}
			}
		});
	}

}
